package com.cskaoyan.market.controller;

import com.cskaoyan.market.db.domain.MarketAdmin;
import com.cskaoyan.market.service.AdminAuthService;
import com.cskaoyan.market.service.impl.AdminAuthServiceImpl;
import com.cskaoyan.market.util.JacksonUtil;
import com.cskaoyan.market.util.MarketConstant;
import com.cskaoyan.market.util.ResponseUtil;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author 远志 zhangsong@cskaoyan.onaliyun.com
 * @Date 2024/6/17 10:49
 * @Version 1.0
 */
@WebServlet("/admin/auth/*")
public class AdminAuthController extends HttpServlet {

    AdminAuthService adminAuthService = new AdminAuthServiceImpl();


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        String op = requestURI.replace(req.getContextPath() + "/admin/auth/", "");
        if("login".equals(op)){
            login(req, resp);
        }
    }

    private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //登录的流程：接收用户提交过来的请求参数，进行比对校验，返回结果
        //获取请求参数：不可以使用request.getParameter来接收，因为不是key=value&key=value模式
        //自行去解析，自己解析请求体 字符数据
        String requestBody = req.getReader().readLine();
        //请求体是一个json字符串，需要解析取出里面的用户名、密码信息，怎么解析，创建一个类，使用这个类来接收
        //但是此时，json字符串里面的参数比较少，创建一个类，觉得有些不值得，所以我们可以使用下面这种方式
        //所以：在一些json字符串中，如果属性比较少，并且此时你不想再去创建一个类时，可以使用下面的方式来处理
        String username = JacksonUtil.parseString(requestBody, "username");
        String password = JacksonUtil.parseString(requestBody, "password");

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            //todo  用户名、密码为空
            Object fail = ResponseUtil.fail(MarketConstant.EMPTY, "用户帐号或密码为空");
            //不要自己去new ObjectMapper，为什么？？因为JacksonUtils里面有，只需要获取即可
            String s = JacksonUtil.getObjectMapper().writeValueAsString(fail);
            //放入响应体
            resp.getWriter().println(s);

            return;
        }
        //后面如果你有其他的需求，比如长度上面的要求，那么再去进一步校验即可
        MarketAdmin admin = adminAuthService.login(username, password);

        //判断登录有没有成功，登录成功返回什么一个对象，登录失败返回什么null
        if(admin != null){
            //登录成功  根据公网抓包的返回结果，应返回下面的内容
            HttpSession session = req.getSession();
            session.setAttribute("admin", admin);

            Map<String, Object> data = new HashMap<>();
            Map<String, String> adminInfo = new HashMap<>();
            adminInfo.put("nickName", admin.getUsername());
            adminInfo.put("avatar", admin.getAvatar());
            data.put("adminInfo", adminInfo);
            //把session的编号返回给前端，它需要
            data.put("token", session.getId());
            Object ok = ResponseUtil.ok(data);
            String s = JacksonUtil.getObjectMapper().writeValueAsString(ok);
            resp.getWriter().println(s);
        }else {
            //登录失败 {"errno":605,"errmsg":"用户帐号或密码不正确"}
            //考虑到无论成功还是失败，返回的结果都有errrno、errmsg，我们可以设计一个通用类来充当结果的封装
            //里面返回的状态码，大家小组可以自行确认
            //系统中只会用0来确认成功，非0确认失败
            Object fail = ResponseUtil.fail(MarketConstant.WRONG_PASSWORD, "用户帐号或密码不正确");
            //不要自己去new ObjectMapper，为什么？？因为JacksonUtils里面有，只需要获取即可
            String s = JacksonUtil.getObjectMapper().writeValueAsString(fail);
            //放入响应体
            resp.getWriter().println(s);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        String op = requestURI.replace(req.getContextPath() + "/admin/auth/", "");
        if("info".equals(op)){
            info(req, resp);
        }

    }

    private void info(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //不需要去接收用户输入的参数，直接返回结果即可
        //响应需要的内容：name、avatar直接从session域获取；perms、roles项目一暂时处理不了，直接写死
        HttpSession session = req.getSession();
        MarketAdmin admin = (MarketAdmin) session.getAttribute("admin");

        Map<String, Object> data = new HashMap<>();
        data.put("roles", Arrays.asList("超级管理员"));
        data.put("name", admin.getUsername());
        data.put("avatar", admin.getAvatar());
        data.put("perms", Arrays.asList("*"));
        Object ok = ResponseUtil.ok(data);
        String s = JacksonUtil.getObjectMapper().writeValueAsString(ok);
        resp.getWriter().println(s);
    }
}
